/**
 * @file memm.h
 * 自定义堆管理接口
 *
 * @author lokliang
 * @brief
 * @version 0.2
 * @date 2022-12-07
 * @date 2022-01-14
 *
 * @copyright Copyright (c) 2022
 *
 */

#ifndef __MEMM_H__
#define __MEMM_H__

#include <stddef.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C"
{
#endif

typedef struct memm_hdl memm_t;

static memm_t *memm_init         (void *mem_base, size_t mem_size);       // 初始化并指定待管理的可用于分配的内存块位置，返回：参数结构体
static void   *memm_malloc       (memm_t *hdl, size_t size);              // 申请大小为 size 字节的连续内存空间，若申请失败返回 NULL，否则返回可使用的内存首址
static void   *memm_calloc       (memm_t *hdl, size_t size);              // 申请大小为 size 字节的连续内存空间并清0，若申请失败返回 NULL，否则返回可使用的内存首址
static void   *memm_malloc_tail  (memm_t *hdl, size_t size);              // 申请大小为 size 字节的连续内存空间，若申请失败返回 NULL，否则返回可使用的内存首址；优先从空闲块的尾部申请
static void   *memm_realloc      (memm_t *hdl, void *p, size_t new_size); // 若成功则返回新空间的地址，原空间被释放；若失败则返回 NULL，其他不变
static int     memm_free         (memm_t *hdl, void *p);                  // 释放内存。成功返回0
static void    memm_free_all     (memm_t *hdl);                           // 一次性快速释放所有内存
static size_t  memm_used_size    (memm_t *hdl);                           // 获取总已使用空间
static size_t  memm_free_size    (memm_t *hdl);                           // 获取总空闲空间（包含所有碎片）
static size_t  memm_block_max    (memm_t *hdl);                           // 获取当前最大的连续空间
static bool    memm_is_valid     (memm_t *hdl, void *p);                  // 获取内存指针是否有效

static size_t memm_get_header_info_size(void);   // 堆的头信息消耗的字节数
static size_t memm_get_block_info_size(void);    // 每个管理块额外消耗的字节数
static size_t memm_get_data_space_size(void *p); // 已申请内存块的实际空间大小（字节）

static void *memm_get_base(memm_t *hdl); // 获取用户定义的内存的基地址
static void *memm_get_end(memm_t *hdl);  // 获取用户定义的内存的结束地址

#ifdef __cplusplus
}
#endif

#endif /* #ifndef __MEMM_H__ */
